﻿/*************************************************************************
 *
 * Copyright (c) 2009-2015 Xuld. All rights reserved.
 * 
 * Project Url: http://work.xuld.net/circus
 * 
 * This source code is part of the Project Circus.
 * 
 * This code is licensed under The Circus License.
 * See the file License.html for the license details.
 * 
 * 
 * You must not remove this notice, or any other, from this software.
 *
 * 
 *************************************************************************/


using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Routing;

namespace Circus.Utility {

    /// <summary>
    /// 提供处理 URL 的辅助函数。
    /// </summary>
    public static class UriHelper {

        /// <summary>
        /// The attach query string parameter.
        /// </summary>
        /// <param name="url">
        /// The url.
        /// </param>
        /// <param name="parameterName">
        /// The parameter name. This value should not be provided by an end user; the caller should
        /// ensure that this value comes only from a literal string.
        /// </param>
        /// <param name="parameterValue">
        /// The parameter value.
        /// </param>
        /// <returns>An absolute URI.</returns>
        public static Uri appendQueryStringParameter(this Uri url, string parameterName, string parameterValue) {
            UriBuilder uriBuilder = new UriBuilder(url);
            string q = uriBuilder.Query;
            if (q.Length > 1) {
                q = q.Substring(1);
            }

            var prefix =  parameterName + "=";
            parameterValue = Uri.EscapeDataString(parameterValue);

            string[] parts = q.Split('&');

            bool shouldAppend = true;

            for (int i = 0; i < parts.Length; i++) {
                if (parts[i].StartsWith(prefix)) {
                    parts[i] = prefix + parameterValue;
                    shouldAppend = false;
                    break;
                }
            }
            if (shouldAppend) {
                if (q.Length > 0) {
                    q += "&";
                }
                q += prefix + parameterValue;
            } else {
                q = String.Join("&", parts);
            }


            uriBuilder.Query = q;
            return uriBuilder.Uri;

        }

        /// <summary>
        /// Converts an app-relative url, e.g. ~/Content/Return.cshtml, to a full-blown url, e.g. http://mysite.com/Content/Return.cshtml
        /// </summary>
        /// <param name="returnUrl">
        /// The return URL. 
        /// </param>
        /// <param name="context">
        /// The context.
        /// </param>
        /// <returns>An absolute URI.</returns>
        public static Uri convertToAbsoluteUri(string returnUrl, HttpContextBase context) {
            if (Uri.IsWellFormedUriString(returnUrl, UriKind.Absolute)) {
                return new Uri(returnUrl, UriKind.Absolute);
            }
            if (!VirtualPathUtility.IsAbsolute(returnUrl)) {
                returnUrl = VirtualPathUtility.ToAbsolute(returnUrl);
            }
            Uri publicFacingUrl = context.Request.Url;
            return new Uri(publicFacingUrl, returnUrl);
        }

        /// <summary>
        /// 生成一个新的地址。
        /// </summary>
        /// <param name="path"></param>
        /// <param name="pathParts"></param>
        /// <returns></returns>
        public static string buildUrl(string path, params object[] pathParts) {
            path = HttpUtility.UrlPathEncode(path);
            if (pathParts.Length > 0) {
                StringBuilder builder = new StringBuilder();
                foreach (object obj2 in pathParts) {
                    if (obj2.GetType().GetInterfaces().Length > 0) {
                        string str = Convert.ToString(obj2, CultureInfo.InvariantCulture);
                        path = path + "/" + HttpUtility.UrlPathEncode(str);
                    } else {
                        RouteValueDictionary dictionary = new RouteValueDictionary(obj2);
                        foreach (KeyValuePair<string, object> pair in dictionary) {
                            if (builder.Length == 0) {
                                builder.Append('?');
                            } else {
                                builder.Append('&');
                            }
                            string str2 = Convert.ToString(pair.Value, CultureInfo.InvariantCulture);
                            builder.Append(HttpUtility.UrlEncode(pair.Key)).Append('=').Append(HttpUtility.UrlEncode(str2));
                        }
                    }
                }
                path += builder;
            }
            return path;
        }

    }

}
